package cn.donting.jme.swing.tab.scene;

import cn.donting.jme.EditorContent;
import cn.donting.jme.editor.scene.Scene;
import cn.donting.jme.event.NameChangeEvent;
import cn.donting.jme.event.SelectEvent;
import cn.donting.jme.event.scene.SceneChangeEvent;
import cn.donting.jme.event.scene.SceneSaveEvent;
import cn.donting.jme.swing.Tab;
import cn.donting.jme.swing.tab.scene.treenode.CameraTreeNode;
import cn.donting.jme.swing.tab.scene.treenode.SceneTreeNode;
import cn.donting.jme.swing.tab.scene.treenode.SpatialTreeNode;
import com.google.common.eventbus.Subscribe;
import com.jme3.scene.Node;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
@Slf4j
public class SceneTreeTab extends Tab {
    public static final int TAB_INDEX = 3;

    public static final String TREE_NODE_DATA_KEY = "TREE_NODE_DATA_KEY";

    private JLabel loadingLabel;

    @Getter
    private JDropTree jTree;
    private JScrollPane jScrollPane;
    private DefaultTreeModel treeModel;
    private Scene scene;
    private File file;

    public SceneTreeTab() {
        setLayout(new BorderLayout());
        loadingLabel = new JLabel("加载中...");
        loadingLabel.setHorizontalAlignment(SwingUtilities.CENTER);
        jTree = new JDropTree();
        jScrollPane = new JScrollPane(jTree);
        EditorContent.registerEvent(this);
        jTree.setRootVisible(false);
        jTree.setDragEnabled(true);
        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        treeModel = new DefaultTreeModel(root);
        jTree.setModel(treeModel);
        setLoading();
        jTree.addContentMenuListeners(this::contentMenu);
        jTree.addTreeSelectionListener(this::treeSelectionChange);
        setTitle("");
    }

    private  void contentMenu(MouseEvent event){
        Object treeNode = jTree.getSelectionPath().getLastPathComponent();
        if (treeNode instanceof CameraTreeNode) {
            ((CameraTreeNode) treeNode).openMenu(event);
            return;
        }
        if (treeNode instanceof SpatialTreeNode) {
            ((SpatialTreeNode) treeNode).openMenu(event);
            return;
        }
    }
    @Override
    public void setLoading() {
        remove(jScrollPane);
        add(loadingLabel,BorderLayout.CENTER);
        loadingLabel.setText("加载中....");
    }

    @Override
    public void setLoadError(Exception e) {
        remove(jScrollPane);
        add(loadingLabel,BorderLayout.CENTER);
        loadingLabel.setText("load error" + e.getMessage());
    }

    public void openScene(Scene scene, File file) {
        this.scene = scene;
        this.file = file;
        setTitle(file.getName());
        EditorContent.getEditorUI().getSceneNode().attachChild(scene.getRootNode());
        loadScene();
        remove(loadingLabel);
        add(jScrollPane, BorderLayout.CENTER);
    }

    private void loadScene(){
        Node rootNode = scene.getRootNode();
        SpatialTreeNode spatialTreeNode = SpatialTreeNode.createTreeNode(jTree,rootNode);
        CameraTreeNode cameraTreeNode = CameraTreeNode.createTreeNode(jTree,scene);
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("ROOT");
        root.add(spatialTreeNode);
        root.add(cameraTreeNode);
        treeModel.setRoot(root);
    }

    private void treeSelectionChange(TreeSelectionEvent e){
        TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
        if (newLeadSelectionPath==null) {
            return;
        }
        Object treeNode = newLeadSelectionPath.getLastPathComponent();
        if (treeNode instanceof SceneTreeNode) {
            SelectEvent selectEvent = ((SceneTreeNode) treeNode).getSelectEvent();
            EditorContent.postEvent(selectEvent);
        }
    }

    @Subscribe
    private void sceneChangeEvent(SceneChangeEvent changeEvent) {
        if (!getTitle().endsWith("*")) {
            setTitle(getTitle() + "*");
        }
    }

    @Subscribe
    private void sceneSaveEvent(SceneSaveEvent sceneSaveEvent) {
        if (getTitle().endsWith("*")) {
            setTitle(getTitle().substring(0, getTitle().length() - 1));
        }
    }

    @Subscribe
    private void nameChangeEvent(NameChangeEvent event) throws IOException {
        Object target = event.getTarget();
        Object objectData = EditorContent.getObjectData(target, TREE_NODE_DATA_KEY);
        if (objectData instanceof TreeNode) {
            treeModel.nodeChanged((TreeNode) objectData);
        }
    }


}
